<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MediaMTX视频监控系统 - 多窗口版</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
    <style>
* {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #1a2a6c, #2c3e50);
            color: #fff;
            min-height: 100vh;
            // padding: 20px;
        }

        ::-webkit-scrollbar {
            width: 8px;
        }

        ::-webkit-scrollbar-track {
            background: rgba(0, 0, 0, 0.2);
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb {
            background: #4e54c8;
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #8f94fb;
        }

        .container {
            max-width: 1800px;
            margin: 0 auto;
            padding: 20px;
        }

        header {
            text-align: center;
            padding: 20px 0;
            margin-bottom: 30px;
            border-bottom: 2px solid rgba(255, 255, 255, 0.1);
            position: relative;
        }

        h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            background: linear-gradient(90deg, #4e54c8, #8f94fb);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        }

        .subtitle {
            color: #a0d2eb;
            font-size: 1.2rem;
            margin-top: 10px;
        }

        .layout-control {
            position: absolute;
            right: 20px;
            top: 50%;
            transform: translateY(-50%);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .layout-select {
            background: rgba(0, 25, 50, 0.8);
            color: white;
            border: 1px solid #4e54c8;
            padding: 10px 15px;
            border-radius: 8px;
            font-size: 1rem;
            cursor: pointer;
        }

        .dashboard {
            display: grid;
            grid-template-columns: 1fr 400px;
            gap: 25px;
            margin-bottom: 30px;
            transition: all 0.3s ease;
        }

        .dashboard.collapsed {
            grid-template-columns: 1fr 50px;
        }

        .video-grid-container {
            background: rgba(0, 15, 30, 0.8);
            border-radius: 15px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
            position: relative;
            display: grid;
            grid-template-columns: repeat(1, 1fr);
            gap: 0;
        }

        .video-grid-2 {
            grid-template-columns: repeat(2, 1fr);
        }

        .video-grid-4 {
            grid-template-columns: repeat(2, 1fr);
            grid-template-rows: repeat(2, 1fr);
        }

        .video-grid-6 {
            grid-template-columns: repeat(3, 1fr);
            grid-template-rows: repeat(2, 1fr);
        }

        .video-grid-8 {
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(2, 1fr);
        }

        .video-grid-12 {
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(3, 1fr);
        }

        .video-grid-16 {
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(4, 1fr);
        }

        .video-cell {
            position: relative;
            border: 1px solid rgba(255, 255, 255, 0.1);
            overflow: hidden;
        }

        .video-wrapper {
            position: relative;
            padding-top: 56.25%;
            /* 16:9 Aspect Ratio */
            background: #000;
        }

        .video-player {
            position: absolute;
            top: 35px;
            left: 0;
            width: 100%;
            height: 100%;
            background: #000;
            object-fit: cover;
        }

        .video-title {
            font-size: 0.9rem;
            color: #fff;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .cell-control-btn {
            background: rgba(78, 84, 200, 0.8);
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 0.8rem;
            transition: all 0.3s;
        }

        .cell-control-btn:hover {
            background: #6a71e6;
        }

        .cell-control-btn.active {
            background: #27ae60;
        }

        .controls {
            padding: 15px 20px;
            background: rgba(0, 20, 40, 0.9);
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            align-items: center;
        }

        .control-btn {
            background: #4e54c8;
            color: white;
            border: none;
            padding: 10px 18px;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 600;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .control-btn:hover {
            background: #6a71e6;
            transform: translateY(-2px);
        }

        .btn-danger {
            background: #e74c3c;
        }

        .btn-danger:hover {
            background: #ff6b5c;
        }

        .btn-success {
            background: #27ae60;
        }

        .btn-success:hover {
            background: #2ecc71;
        }

        .btn-warning {
            background: #f39c12;
        }

        .btn-warning:hover {
            background: #f1c40f;
        }

        .status-bar {
            display: flex;
            justify-content: space-between;
            padding: 15px 20px;
            background: rgba(0, 25, 50, 0.8);
            border-top: 1px solid rgba(255, 255, 255, 0.1);
        }

        .status-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            min-width: 100px;
        }

        .status-label {
            font-size: 0.9rem;
            color: #a0d2eb;
            margin-bottom: 5px;
        }

        .status-value {
            font-size: 1.2rem;
            font-weight: 700;
        }

        .panel {
            background: rgba(0, 15, 30, 0.8);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .panel.collapsed {
            padding: 15px 5px;
            width: 50px;
        }

        .toggle-panel {
            position: absolute;
            top: 15px;
            right: 15px;
            background: rgba(78, 84, 200, 0.8);
            color: white;
            border: none;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 20;
        }

        .toggle-panel:hover {
            background: #6a71e6;
        }

        .panel-content {
            transition: opacity 0.3s ease;
        }

        .panel.collapsed .panel-content {
            opacity: 0;
            pointer-events: none;
        }

        .panel-title {
            font-size: 1.4rem;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 2px solid #4e54c8;
            color: #8f94fb;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            color: #a0d2eb;
            font-weight: 500;
        }

        select,
        input {
            width: 100%;
            padding: 12px;
            border-radius: 8px;
            border: 1px solid #4e54c8;
            background: rgba(0, 20, 40, 0.7);
            color: white;
            font-size: 1rem;
        }

        input[type="datetime-local"] {
            padding: 10px 8px 10px 8px;

        }

        .cameras-grid {
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
        }

        .camera-card {
            background: rgb(11 40 69 / 70%);
            border-radius: 10px;
            padding: 6px;
            cursor: pointer;
            transition: all 0.3s;
            border: 2px solid transparent;
            margin-top: 10px;
        }

        .camera-card:hover {
            transform: translateY(-5px);
            border-color: #4e54c8;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }

        .camera-card.active {
            border-color: #27ae60;
            background: rgba(0, 40, 20, 0.7);
        }

        .camera-title {
            font-size: 1.2rem;
            margin-bottom: 5px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .camera-status {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
        }

        .status-online {
            background: #27ae60;
            box-shadow: 0 0 10px #27ae60;
        }

        .status-offline {
            background: #e74c3c;
        }

        .camera-info {
            color: #a0d2eb;
            font-size: 0.9rem;
            margin-top: 8px;
        }

        .timestamp {
            font-size: 0.85rem;
            color: #7f8c8d;
            margin-top: 5px;
        }

        .spinner {
            width: 40px;
            height: 40px;
            border: 4px solid rgba(255, 255, 255, 0.3);
            border-radius: 50%;
            border-top-color: #4e54c8;
            animation: spin 1s ease-in-out infinite;
            margin-bottom: 15px;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        .error-box {
            background: rgba(231, 76, 60, 0.2);
            border: 1px solid #e74c3c;
            border-radius: 10px;
            display: none;
        }

        .error-title {
            color: #e74c3c;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 1.2rem;
        }

        .error-message {
            font-family: monospace;
            background: rgba(0, 0, 0, 0.3);
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            font-size: 0.95rem;
        }

        footer {
            text-align: center;
            margin-top: 40px;
            padding: 25px;
            color: #a0d2eb;
            font-size: 0.95rem;
            border-top: 1px solid rgba(255, 255, 255, 0.1);
        }

        .video-grid-container {
            transition: all 0.3s ease;
        }

        .loading-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 5;
            color: white;
            pointer-events: none;
        }

        .video-controls {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 8px 10px;
            background: rgba(0, 20, 40, 0.9);
            display: flex;
            justify-content: center;
            gap: 5px;
            z-index: 10;
        }

        .video-header {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            padding: 8px 15px;
            background: rgba(0, 20, 40, 0.9);
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 10;
        }

        .video-cell.active-cell {
            border: 2px solid #27ae60;
            box-shadow: 0 0 15px rgba(39, 174, 96, 0.5);
        }

        /* 修改选中状态的样式 */
        .video-cell.active-cell {
            border: 2px solid #27ae60;
            box-shadow: 0 0 15px rgba(39, 174, 96, 0.5);
        }

        /* 修改选择按钮的样式 */
        .cell-control-btn[data-action="select"] {
            display: none;
            /* 隐藏选择按钮 */
        }

        @media (max-width: 1100px) {
            .dashboard {
                grid-template-columns: 1fr;
            }

            .dashboard.collapsed {
                grid-template-columns: 1fr;
            }

            .cameras-grid {
                grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
            }
        }

        @media (max-width: 768px) {
            .controls {
                flex-direction: column;
                align-items: stretch;
            }

            .status-bar {
                flex-wrap: wrap;
            }

            .status-item {
                flex: 1 0 45%;
                margin-bottom: 15px;
            }

            h1 {
                font-size: 2.2rem;
            }

            .layout-control {
                position: static;
                transform: none;
                margin-top: 15px;
                justify-content: center;
            }
        }
        .breadcrumb {
            font-size: 14px;
            margin-bottom: 10px;
            color: #666;
        }

        .breadcrumb a {
            color: #4a6fa5;
            text-decoration: none;
        }

        .breadcrumb a:hover {
            text-decoration: underline;
        }

        .breadcrumb .separator {
            margin: 0 5px;
            color: #999;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <div class="breadcrumb">
            <a href="/index">主页</a>
            <span class="separator">/</span>
            <span>实时监控</span>
        </div>
    </div>

    <div class="dashboard" id="dashboard">
        <div class="video-grid-container" id="videoGrid">
            <!-- 视频窗口将动态生成 -->
        </div>

        <div class="panel" id="controlPanel">
            <button class="toggle-panel" id="togglePanel">
                <i class="fas fa-chevron-right"></i>
            </button>
            <div class="panel-content">
                <h2 class="panel-title"><i class="fas fa-sliders-h"></i> 控制面板</h2>

                <div class="form-group">
                    <label for="cameraSelect"><i class="fas fa-th-large"></i> 窗口选择</label>
                    <select class="layout-select" id="layoutSelect">
                        <option value="1">1个窗口</option>
                        <option value="2">2个窗口</option>
                        <option value="4" selected>4个窗口</option>
                        <option value="6">6个窗口</option>
                        <option value="8">8个窗口</option>
                        <option value="12">12个窗口</option>
                        <option value="16">16个窗口</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="cameraSelect"><i class="fas fa-camera"></i> 选择摄像头</label>
                    <select id="cameraSelect" class="form-control">
                    </select>
                </div>
                <div class="error-box" id="errorBox">
                    <h3 class="error-title"><i class="fas fa-exclamation-triangle"></i> 连接错误</h3>
                    <div class="error-message" id="errorMessage"></div>
                    <button id="retryBtn" class="control-btn btn-danger" style="margin-top: 15px; width: 100%;">
                        <i class="fas fa-redo-alt"></i> 重试连接
                    </button>
                </div>
                <div>
                    <h2 class="panel-title"><i class="fas fa-th"></i> 摄像头列表</h2>
                    <div class="cameras-grid" style="margin-top: 20px; height: 47vh;overflow-y: auto;overflow-x: hidden;"
                         id="camerasGrid">
                    </div>

                </div>
            </div>
        </div>
    </div>

    <script>

        // DOM元素
        const layoutSelect = document.getElementById('layoutSelect');
        const videoGrid = document.getElementById('videoGrid');
        const togglePanel = document.getElementById('togglePanel');
        const controlPanel = document.getElementById('controlPanel');
        const dashboard = document.getElementById('dashboard');
        const cameraSelect = document.getElementById('cameraSelect');
        const camerasGrid = document.getElementById('camerasGrid');
        
        // 状态管理
        let currentLayout = 4; // 默认4个窗口
        let isPanelCollapsed = false;
        let activeVideoCell = null;
        let activeConnections = {}; // 存储WebRTC连接
        let cameraList = [];    // 存储摄像头列表
        
        // 初始化页面
        async function initPage() {
            // 加载摄像头列表
            cameraList = await loadCameras();
            
            // 渲染摄像头列表
            renderCamerasGrid();
            
            // 初始化视频网格
            createVideoGrid(currentLayout);
            
            // 设置事件监听器
            setupEventListeners();

            // 默认选中第一个视频网格
            toggleActiveVideoCell(0);
        }


        // 修改创建视频网格函数，移除选择按钮
        function createVideoGrid(layoutCount) {
            videoGrid.innerHTML = '';
            currentLayout = layoutCount;
            
            // 移除所有现有的布局类
            videoGrid.className = 'video-grid-container';
            if (layoutCount > 1) {
                videoGrid.classList.add(`video-grid-${layoutCount}`);
            }
            
            for (let i = 0; i < layoutCount; i++) {
                const cell = document.createElement('div');
                cell.className = 'video-cell';
                cell.dataset.index = i;
                
                cell.innerHTML = `
                    <div class="video-header">
                        <div class="video-title">视频窗口 ${i + 1}</div>
                    </div>
                    <div class="video-wrapper">
                        <video class="video-player" autoplay playsinline></video>
                        <div class="loading-overlay" style="display:none;">
                            <div class="spinner"></div>
                            <p>正在连接...</p>
                        </div>
                    </div>
                    <div class="error-box" style="display:none;">
                        <h3 class="error-title"><i class="fas fa-exclamation-triangle"></i> 连接错误</h3>
                        <div class="error-message"></div>
                        <button class="control-btn btn-danger retry-btn" style="margin-top: 15px; width: 100%;">
                            <i class="fas fa-redo-alt"></i> 重试连接
                        </button>
                    </div>
                    <div class="video-controls">
                        <button class="cell-control-btn" data-action="snapshot"><i class="fas fa-camera"></i> 截图</button>
                        <button class="cell-control-btn" data-action="fullscreen"><i class="fas fa-expand"></i> 全屏</button>
                    </div>
                `;
                
                videoGrid.appendChild(cell);
            }
            
            // 重置活动单元格
            activeVideoCell = null;
        }

        // 加载摄像头列表
        async function loadCameras() {
            let cameras = null;
            try {
                const response = await fetch('/api/cameras');
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const data = await response.json();
                cameras = data['cameras'];
                if (cameras && cameras.length > 0) {
                    cameraSelect.innerHTML = '<option value="">-- 请选择摄像头 --</option>' +
                        cameras.map(camera =>
                            `<option value="${camera.id}">${camera.name} (${camera.ip})</option>`
                        ).join('');
                } else {
                    cameraSelect.innerHTML = '<option value="">-- 没有可用的摄像头 --</option>';
                }
            } catch (error) {
                console.error('加载摄像头列表失败:', error);
            }
            return cameras
        }
		
		// 修改设置活动视频单元格函数，实现点击切换选中状态
        function toggleActiveVideoCell(index) {
            const cell = document.querySelector(`.video-cell[data-index="${index}"]`);
            
            // 如果点击的是已选中的单元格，则取消选中
            if (activeVideoCell === index) {
                cell.classList.remove('active-cell');
                activeVideoCell = null;
            } 
            // 否则设置新的活动单元格
            else {
                // 移除之前单元格的选中状态
                if (activeVideoCell !== null) {
                    const prevCell = document.querySelector(`.video-cell[data-index="${activeVideoCell}"]`);
                    if (prevCell) prevCell.classList.remove('active-cell');
                }
                
                // 设置新单元格为选中状态
                cell.classList.add('active-cell');
                activeVideoCell = index;
            }
        }
        
        // 设置活动视频单元格
        function setActiveVideoCell(index) {
            // 移除之前所有单元格的active-cell类
            document.querySelectorAll('.video-cell').forEach(cell => {
                cell.classList.remove('active-cell');
            });
            
            // 设置新的活动单元格
            const cell = document.querySelector(`.video-cell[data-index="${index}"]`);
            if (cell) {
                cell.classList.add('active-cell');
                activeVideoCell = index;
                
                // 更新选择按钮状态
                const selectBtn = cell.querySelector('[data-action="select"]');
                if (selectBtn) {
                    selectBtn.classList.add('active');
                }
            }
        }
        
        // 渲染摄像头网格
        function renderCamerasGrid() {
            camerasGrid.innerHTML = '';
            cameraList.forEach(camera => {
                const cameraCard = document.createElement('div');
                cameraCard.className = `camera-card ${camera.status == 'offline' ? 'disabled' : ''}`;
                cameraCard.dataset.id = camera.id;
                cameraCard.innerHTML = `
                    <h3 class="camera-title">
                        <span class="camera-status status-${camera.status}"></span>
                        ${camera.name}
                    </h3>
                    <div class="camera-info">位置: ${camera.location}</div>
                    <div class="camera-info">状态: ${camera.status == 'online' ? '在线' : '离线'}</div>
                `;
                
                if (camera.status === 'online') {
                    cameraCard.addEventListener('click', () => {
                        cameraSelect.value = camera.id;
                        if (activeVideoCell !== null) {
                            const cell = document.querySelector(`.video-cell[data-index="${activeVideoCell}"]`);
                            if (cell) {
                                const title = cell.querySelector('.video-title');
                                if (title) title.textContent = camera.name;
                                connectToCamera(camera.id, activeVideoCell);
                            }
                        } else {
                            alert("视频窗口未选中状态");
                        }
                    });
                }
                
                camerasGrid.appendChild(cameraCard);
            });
        }
        
        // 设置事件监听器
        function setupEventListeners() {
            // 布局选择
            layoutSelect.addEventListener('change', (e) => {
                const newLayout = parseInt(e.target.value);
                if (newLayout !== currentLayout) {
                    createVideoGrid(newLayout);
                }
            });
            
            // 面板折叠/展开
            togglePanel.addEventListener('click', () => {
                isPanelCollapsed = !isPanelCollapsed;
                
                if (isPanelCollapsed) {
                    controlPanel.classList.add('collapsed');
                    dashboard.classList.add('collapsed');
                    togglePanel.innerHTML = '<i class="fas fa-chevron-left"></i>';
                } else {
                    controlPanel.classList.remove('collapsed');
                    dashboard.classList.remove('collapsed');
                    togglePanel.innerHTML = '<i class="fas fa-chevron-right"></i>';
                }
            });
            
            // 窗口控制按钮
            videoGrid.addEventListener('click', (e) => {
                // 如果点击的是视频框本身或其中的非按钮元素
                const cell = e.target.closest('.video-cell');
                if (cell && !e.target.closest('.video-controls')) {
                    const index = parseInt(cell.dataset.index);
                    toggleActiveVideoCell(index);
                }
                
                // 处理控制按钮点击
                const actionBtn = e.target.closest('[data-action]');
                if (actionBtn) {
                    const action = actionBtn.dataset.action;
                    const cell = actionBtn.closest('.video-cell');
                    
                    if (cell) {
                        const index = parseInt(cell.dataset.index);
                        
                        switch(action) {
                            case 'snapshot':
                                takeSnapshot(index);
                                break;
                            case 'fullscreen':
                                toggleFullscreen(index);
                                break;
                        }
                    }
                }

            });
            
            // 全局控制按钮
            document.getElementById('retryBtn').addEventListener('click', () => {
                if (activeVideoCell !== null && cameraSelect.value) {
                    connectToCamera(cameraSelect.value, activeVideoCell);
                }
            });
            
            // 摄像头选择变化
            cameraSelect.addEventListener('change', (e) => {
                if (activeVideoCell !== null) {
                    const cameraId = e.target.value;
                    const camera = cameraList.find(c => c.id === parseInt(cameraId));
                    if (camera) {
                        const cell = document.querySelector(`.video-cell[data-index="${activeVideoCell}"]`);
                        if (cell) {
                            const title = cell.querySelector('.video-title');
                            if (title) title.textContent = camera.name;
                            cell.dataset.cameraId = cameraId;
                            connectToCamera(cameraId, activeVideoCell);
                        }
                    }
                } else {
                    alert("视频窗口未选中状态");
                }
            });
        }
        
        // 连接到摄像头
        async function connectToCamera(cameraId, cellIndex) {
            const camera = cameraList.find(c => c.id === parseInt(cameraId));
            if (!camera) return;
            
            const videoCell = document.querySelector(`.video-cell[data-index="${cellIndex}"]`);
            if (!videoCell) return;
            
            const videoWrapper = videoCell.querySelector('.video-wrapper');
            const video = videoCell.querySelector('.video-player');
            const loading = videoWrapper.querySelector('.loading-overlay');
            const errorBox = videoCell.querySelector('.error-box');
            const errorMessage = videoCell.querySelector('.error-message');
            const title = videoCell.querySelector('.video-title');
            
            // 显示加载状态
            loading.style.display = 'flex';
            errorBox.style.display = 'none';
            title.textContent = camera.name;
            video.srcObject = null;
            video.src = '';
            
            // 清除之前的连接
            if (activeConnections[cellIndex]) {
                activeConnections[cellIndex].close();
                delete activeConnections[cellIndex];
            }
            console.log(activeConnections);
            try {
                // 设置超时 (30秒)
                const timeout = setTimeout(() => {
                    throw new Error('连接超时 (30秒)');
                }, 30000);
                
                // 尝试WebRTC
                await connectWithWebRTC(camera, video, loading, errorBox, errorMessage, cellIndex);
                
                clearTimeout(timeout);
            } catch (error) {
                console.error('WebRTC连接失败:', error);
                errorMessage.textContent = `WebRTC连接失败: ${error.message}`;
                errorBox.style.display = 'block';
                loading.style.display = 'none';
            }
        }

        async function connectWithWebRTC(camera, video, loading, errorBox, errorMessage, cellIndex) {
            try {
                // 1. 创建PeerConnection
                const pc = new RTCPeerConnection({
                    iceServers: [
                        {urls: 'stun:stun.l.google.com:19302'}
                    ]
                });

                // 存储连接以便后续管理
                activeConnections[cellIndex] = pc;

                // 2. 设置事件处理器
                pc.ontrack = (event) => {
                    if (event.track.kind === 'video') {
                        video.srcObject = event.streams[0];
                        loading.style.display = 'none';
                    }
                };

                pc.oniceconnectionstatechange = () => {
                    if (pc.iceConnectionState === 'failed') {
                        errorMessage.textContent = 'ICE连接失败';
                        errorBox.style.display = 'block';
                    }
                };

                // 3. 添加视频接收器
                pc.addTransceiver('video', {direction: 'recvonly'});

                // 4. 创建Offer
                const offer = await pc.createOffer();
                await pc.setLocalDescription(offer);

                // 5. 通过后端发送Offer到MediaMTX
                const token = localStorage.getItem('token');
                const response = await fetch(`/api/stream/${camera.id}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${token}`
                    },
                    body: JSON.stringify({
                        offer: offer.sdp
                    })
                });
console.log("connectWithWebRTC", response);
                if (!response.ok) {
                    const error = await response.json();
                    throw new Error(error.error || '信令服务器错误');
                }

                // 6. 处理Answer
                const data = await response.json();
                await pc.setRemoteDescription({
                    type: data.type,
                    sdp: data.sdp
                });

            } catch (error) {
                console.error('WebRTC连接失败:', error);
                errorMessage.textContent = `连接失败: ${error.message}`;
                errorBox.style.display = 'block';
                loading.style.display = 'none';

                // 清理失败的连接
                if (activeConnections[cellIndex]) {
                    activeConnections[cellIndex].close();
                    delete activeConnections[cellIndex];
                }

                // 处理认证错误
                if (error.message.includes('Unauthorized')) {
                    localStorage.removeItem('token');
                    window.location.href = '/login';
                }
            }
        }
        
        // 截图
        function takeSnapshot(index) {
            const cell = document.querySelector(`.video-cell[data-index="${index}"]`);
            const video = cell.querySelector('.video-player');
            const loading = cell.querySelector('.loading-overlay');
    
            if (!video || !video.srcObject) return;
            
            // 临时隐藏加载状态（如果有）
            const loadingVisible = loading.style.display === 'flex';
            if (loadingVisible) loading.style.display = 'none';
            
            const canvas = document.createElement('canvas');
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            
            const ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            
            const link = document.createElement('a');
            link.download = `snapshot-${new Date().toISOString().slice(0,19).replace(/:/g,'-')}-${index+1}.png`;
            link.href = canvas.toDataURL('image/png');
            link.click();
            
            if (loadingVisible) loading.style.display = 'flex';
        }
        
        // 切换全屏
        function toggleFullscreen(index) {
            const videoWrapper = document.querySelector(`.video-cell[data-index="${index}"] .video-wrapper`);
            if (!videoWrapper) return;
            
            if (!document.fullscreenElement) {
                if (videoWrapper.requestFullscreen) {
                    videoWrapper.requestFullscreen();
                } else if (videoWrapper.mozRequestFullScreen) {
                    videoWrapper.mozRequestFullScreen();
                } else if (videoWrapper.webkitRequestFullscreen) {
                    videoWrapper.webkitRequestFullscreen();
                } else if (videoWrapper.msRequestFullscreen) {
                    videoWrapper.msRequestFullscreen();
                }
            } else {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitExitFullscreen) {
                    document.webkitExitFullscreen();
                } else if (document.msExitFullscreen) {
                    document.msExitFullscreen();
                }
            }
        }
        // 初始化页面
        window.addEventListener('load', initPage);
    </script>
</body>
<footer>
    &copy; 2025 视频监控系统 | 版本 1.0.0
</footer>
</html>